home *** CD-ROM | disk | FTP | other *** search
/ 10,000 Great Games / 10,000 Great Games.iso / Product / 66 / data1.cab / Source_Files / Src / Props.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  10KB  |  600 lines

  1. #include "stdafx.h"
  2.  
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. cProperties *props = 0;
  7.  
  8. static cProperties *find = 0;
  9. static char *find_name = 0, *find_type = 0;
  10.  
  11. static cParse *pars;
  12. static cProperties *cp;
  13. static char *cl;
  14.  
  15. cProperties::cProperties()
  16.     add_end((cList **)&props);
  17.     
  18.     // Set name and type
  19.     
  20.     type = "";
  21.     objtype = 0;
  22.     name = "";
  23.     
  24.     // Reset images
  25.     
  26.     images = 0;
  27.     
  28.     // Reset sounds
  29.     
  30.     sounds = 0;
  31.     
  32.     // Reset boundaries
  33.     
  34.     line = 0;
  35.     box = 0;
  36.     spot = 0;
  37.     circle = 0;
  38.     
  39.     // Reset random level options
  40.  
  41.     placement = PLACEMENT_NEVER;
  42.     no_overlap = TRUE;
  43.     occurence = 1000;
  44.     link_to = 0;
  45.  
  46.     // Reset cmap
  47.     
  48.     cmap = 0;
  49.     
  50.     // Reset extra parameters
  51.     
  52.     params = 0;
  53. }
  54.  
  55. cProperties::~cProperties()
  56. {
  57.     // Delete images
  58.     
  59.     images->delete_list();
  60.     
  61.     // Delete sounds
  62.     
  63.     sounds->delete_list();
  64.  
  65.     // Delete linkto's
  66.  
  67.     link_to->delete_list();
  68.  
  69.     // Delete boundaries
  70.     
  71.     line->delete_list();
  72.     box->delete_list();
  73.     spot->delete_list();
  74.     circle->delete_list();
  75.     
  76.     // Delete extra parameters
  77.     
  78.     params->delete_list();
  79. }
  80.  
  81. void cProperties::go_next()
  82. {
  83.     pars = (cParse *)pars->next;
  84. }
  85. void cProperties::add_sound()
  86. {
  87.     // Add sound
  88.     
  89.     cSound *s = new cSound(&(cp->sounds));
  90.     s->sample = cWAV::get(pars->value);
  91.     s->label = cl;
  92.     
  93.     // Get parameters
  94.     
  95.     go_next();
  96.     
  97.     while (pars != 0)
  98.     {
  99.         if (pars->cmp("LOOP"))
  100.         {
  101.             s->loop = pars->value_true();
  102.             
  103.             go_next();
  104.         }
  105.         
  106.         else if (pars->cmp("DURATION"))
  107.         {
  108.             s->duration = (int)(atof(pars->value) * sec);
  109.             
  110.             go_next();
  111.         }
  112.         
  113.         else if (pars->cmp("VOLUME"))
  114.         {
  115.             s->volume = atoi(pars->value);
  116.             
  117.             go_next();
  118.         }
  119.         
  120.         // Otherwise go back
  121.         
  122.         else
  123.             break;
  124.     }
  125. }
  126.  
  127. void cProperties::add_image()
  128. {
  129.     // Add image
  130.     
  131.     cImage *i = new cImage(&(cp->images));
  132.     
  133.     i->bmp = cBMP::get(pars->value);
  134.     
  135.     i->label = cl;
  136.     
  137.     i->origin_x = i->bmp->w / 2;
  138.     i->origin_y = i->bmp->h / 2;
  139.     
  140.     // Get parameters
  141.     
  142.     go_next();
  143.     
  144.     while (pars != 0)
  145.     {
  146.         if (pars->cmp("DELAY"))
  147.         {
  148.             i->delay = (int)(atof(pars->value)*sec);
  149.             
  150.             go_next();
  151.         }
  152.         
  153.         else if (pars->cmp("COLORMAP"))
  154.         {
  155.             i->cmap = (char *)cData::get(pars->value);
  156.             
  157.             go_next();
  158.         }
  159.  
  160.         else if (pars->cmp("GRAVITY"))
  161.         {
  162.             i->gmap = (short *)cData::get(pars->value);
  163.  
  164.             go_next();
  165.         }
  166.         
  167.         else if (pars->cmp("ORIGIN"))
  168.         {
  169.             char x, y;
  170.             
  171.             if (sscanf(pars->value, "%c%d,%c%d", &x, &(i->origin_x), &y, &(i->origin_y)) != 4)
  172.                 pars->invalid_line();
  173.             
  174.             switch(toupper(x))
  175.             {
  176.             case 'L':
  177.                 break;
  178.                 
  179.             case 'C':
  180.             case 'M':
  181.                 i->origin_x += i->bmp->w / 2;
  182.                 break;
  183.                 
  184.             case 'R':
  185.                 i->origin_x += i->bmp->w - 1;
  186.                 break;
  187.                 
  188.             default:
  189.                 pars->invalid_line();
  190.             }
  191.             
  192.             switch(toupper(y))
  193.             {
  194.             case 'T':
  195.                 break;
  196.                 
  197.             case 'C':
  198.             case 'M':
  199.                 i->origin_y += i->bmp->h / 2;
  200.                 break;
  201.                 
  202.             case 'B':
  203.                 i->origin_y += i->bmp->h - 1;
  204.                 break;
  205.                 
  206.             default:
  207.                 pars->invalid_line();
  208.             }
  209.             
  210.             go_next();
  211.         }
  212.         
  213.         // Otherwise go back
  214.         
  215.         else
  216.             break;
  217.     }        
  218. }
  219.  
  220.  
  221. void cProperties::add_linkto()
  222. {
  223.     int x, y;
  224.     
  225.     // Create linkto object
  226.  
  227.     cLinkTo *l = new cLinkTo(&cp->link_to);
  228.  
  229.     // Store occurence
  230.  
  231.     l->chance = atoi(pars->value);
  232.  
  233.     go_next();
  234.  
  235.     // Set other properties
  236.  
  237.     while (pars != 0)
  238.     {
  239.         if (pars->cmp("TYPE"))
  240.         {
  241.             l->type = pars->value;
  242.  
  243.             go_next();
  244.         }
  245.  
  246.         else if (pars->cmp("NAME"))
  247.         {
  248.             l->name = pars->value;
  249.  
  250.             go_next();
  251.         }
  252.  
  253.         else if (pars->cmp("SPOT"))
  254.         {
  255.             if (sscanf(pars->value, "%d,%d", &x, &y) != 2)
  256.                 pars->invalid_line();
  257.  
  258.             l->position.x = x, l->position.y = y;
  259.  
  260.             go_next();
  261.         }
  262.  
  263.         else
  264.             break;
  265.     }
  266. }
  267.  
  268. void cProperties::add_type()
  269. {
  270.     int x1, y1, x2, y2;
  271.     
  272.     // New property object
  273.     
  274.     cp = new cProperties ();
  275.  
  276.     cp->type = pars->value;
  277.     cp->objtype = cObjectTypes::find(pars->value);
  278.     
  279.     // Reset label
  280.     
  281.     cl = "";
  282.     
  283.     // Get parameters
  284.     
  285.     go_next();
  286.     
  287.     while (pars != 0)
  288.     {
  289.         if (pars->cmp("NAME"))
  290.         {
  291.             cp->name = pars->value;
  292.             
  293.             go_next();
  294.         }
  295.         
  296.         else if (pars->cmp("LINE"))
  297.         {
  298.             if (sscanf(pars->value, "%d,%d,%d,%d", &x1, &y1, &x2, &y2) != 4)
  299.                 pars->invalid_line();
  300.             
  301.             new cLine (&(cp->line), x1, y1, x2, y2, cl);
  302.             
  303.             go_next();
  304.         }
  305.         
  306.         else if (pars->cmp("BOX"))
  307.         {
  308.             if (sscanf(pars->value, "%d,%d,%d,%d", &x1, &y1, &x2, &y2) != 4 || x1 > x2 || y1 > y2)
  309.                 pars->invalid_line();
  310.  
  311.             new cBox (&(cp->box), x1, y1, x2, y2, cl);
  312.             
  313.             go_next();
  314.         }
  315.         
  316.         else if (pars->cmp("SPOT"))
  317.         {
  318.             if (sscanf(pars->value, "%d,%d", &x1, &y1) != 2)
  319.                 pars->invalid_line();
  320.             
  321.             new cSpot (&(cp->spot), x1, y1, cl);
  322.             
  323.             go_next();
  324.         }
  325.         
  326.         else if (pars->cmp("RADIUS"))
  327.         {
  328.             if (sscanf(pars->value, "%d", &x2) != 1)
  329.                 pars->invalid_line();
  330.             
  331.             new cCircle(&(cp->circle), 0, 0, x2, cl);
  332.             
  333.             go_next();
  334.         }
  335.         
  336.         else if (pars->cmp("CIRCLE"))
  337.         {
  338.             if (sscanf(pars->value, "%d,%d,%d", &x1, &y1, &x2) != 3)
  339.                 pars->invalid_line();
  340.             
  341.             new cCircle(&(cp->circle), x1, y1, x2, cl);
  342.             
  343.             go_next();
  344.         }
  345.  
  346.         else if (pars->cmp("PLACEMENT"))
  347.         {
  348.             if (eq(pars->value, "NEVER"))
  349.                 cp->placement = PLACEMENT_NEVER;
  350.             else if (eq(pars->value, "PLATFORM"))
  351.                 cp->placement = PLACEMENT_PLATFORM;
  352.             else if (eq(pars->value, "ANY"))
  353.                 cp->placement = PLACEMENT_ANY;
  354.             else if (eq(pars->value, "ON PLATFORM"))
  355.                 cp->placement = PLACEMENT_ON_PLATFORM;
  356.             else if (eq(pars->value, "BETWEEN PLATFORMS"))
  357.                 cp->placement = PLACEMENT_BETWEEN_PLATFORMS;
  358.             else if (eq(pars->value, "UNDER PLATFORM"))
  359.                 cp->placement = PLACEMENT_UNDER_PLATFORM;
  360.             else
  361.                 pars->invalid_line();
  362.  
  363.             go_next();
  364.         }
  365.  
  366.         else if (pars->cmp("NO_OVERLAP"))
  367.         {
  368.             cp->no_overlap = pars->value_true();
  369.  
  370.             go_next();
  371.         }
  372.  
  373.         else if (pars->cmp("BOUNDING_BOX"))
  374.         {
  375.             if (sscanf(pars->value, "%d,%d,%d,%d", &cp->bbox.x1, &cp->bbox.y1, &cp->bbox.x2, &cp->bbox.y2) != 4
  376.                 || cp->bbox.x1 > cp->bbox.x2 
  377.                 || cp->bbox.y1 > cp->bbox.y2)
  378.                 pars->invalid_line();
  379.  
  380.             go_next();
  381.         }
  382.  
  383.         else if (pars->cmp("LINKTO"))
  384.             add_linkto();
  385.  
  386.         else if (pars->cmp("OCCURENCE"))
  387.         {
  388.             cp->occurence = atoi(pars->value);
  389.  
  390.             go_next();
  391.         }
  392.  
  393.         else if (pars->cmp("COLORMAP"))
  394.         {
  395.             cp->cmap = (char *)cData::get(pars->value);
  396.             
  397.             go_next();
  398.         }
  399.         
  400.         else if (pars->cmp("LABEL") || pars->cmp("SEQUENCE") || pars->cmp("SOUNDSEQUENCE"))
  401.         {
  402.             cl = pars->value;
  403.             
  404.             go_next();
  405.         }
  406.         
  407.         else if (pars->label[0] == '*')
  408.         {
  409.             new cParse (&(cp->params), pars);
  410.             
  411.             go_next();
  412.         }
  413.         
  414.         else if (pars->cmp("IMAGE"))
  415.             add_image();
  416.         
  417.         else if (pars->cmp("SOUND"))
  418.             add_sound();
  419.         
  420.         // Otherwise go back
  421.         
  422.         else
  423.             break;
  424.   }
  425.  
  426. void cProperties::create_all(cParse *p)
  427. {       
  428.     pars = p;
  429.     
  430.     while (pars != 0)
  431.     {
  432.         // Check if new object has to be made
  433.         
  434.         if (pars->cmp("TYPE"))
  435.             add_type();
  436.         
  437.         // Otherwise there's an error
  438.         
  439.         else
  440.             pars->invalid_line();
  441.     }
  442. }
  443.  
  444. cProperties *cProperties::find_first(char *type, char *name)
  445. {
  446.     find = props, find_name = name, find_type = type;
  447.     
  448.     return find_next();
  449. }
  450.  
  451. cProperties *cProperties::find_next()
  452. {
  453.     for (; find != 0; find = (cProperties *)find->next)
  454.         if ((find_name == 0 || eq(find->name, find_name))
  455.             && (find_type == 0 || eq(find->type, find_type)))
  456.         {
  457.             cProperties *found = find;
  458.             
  459.             find = (cProperties *)find->next;
  460.             
  461.             return found;
  462.         }
  463.         
  464.     return 0;
  465. }
  466.  
  467. cProperties *cProperties::find_w_error(char *type, char *name)
  468. {
  469.     cProperties *p = cProperties::find_first(type, name);
  470.     
  471.     if (p == 0)
  472.         error("Unable to find object \"%s\"/\"%s\"", type == 0? "ALL":type, name == 0? "ALL":name);
  473.     
  474.     return p;
  475. }
  476.  
  477. int cProperties::sequence_exists(char *_name)
  478. {
  479.     ASSERT(_name != 0);
  480.  
  481.     for (cImage *i = images; i != 0 && !eq(_name, i->label); i = (cImage *)i->next);
  482.  
  483.     return i != 0;
  484. }
  485.  
  486. void cProperties::get_sequence(char *_name, cAnimation &anim)
  487. {
  488.     // Check if all images are requested
  489.     
  490.     if (_name == 0)
  491.     {
  492.         anim.start_frame = images,
  493.         anim.end_frame = (cImage *)cList::get_end(images);
  494.         
  495.         return;
  496.     }
  497.     
  498.     // Search for name
  499.     
  500.     cImage *i;
  501.     
  502.     for (i = images; i != 0 && !eq(_name, i->label); i = (cImage *)i->next);
  503.  
  504.     // Check if there is a sequence
  505.  
  506.     if (i == 0)
  507.     {
  508.         anim.start_frame = 0;
  509.         anim.end_frame = 0;
  510.  
  511.         return;
  512.     }
  513.  
  514.     // Else store first picture
  515.     
  516.     anim.start_frame = i;
  517.     
  518.     // Get end of animation
  519.     
  520.     for (; i->next != 0 && eq(_name, ((cImage *)i->next)->label); i = (cImage *)i->next);
  521.     
  522.     anim.end_frame = i;
  523. }
  524.  
  525. int cProperties::soundsequence_exists(char *_name)
  526. {    
  527.     ASSERT(_name != 0);
  528.  
  529.     for (cSound *s = sounds; s != 0 && !eq(_name, s->label); s = (cSound *)s->next);
  530.  
  531.     return s != 0;
  532. }
  533.  
  534. void cProperties::get_soundsequence(char *_name, cSoundSequence &seq)
  535. {
  536.     // Check if all sounds are requested
  537.     
  538.     if (_name == 0)
  539.     {
  540.         seq.start_sound = sounds;
  541.         seq.end_sound = (cSound *)cList::get_end(sounds);
  542.         
  543.         return;
  544.     }
  545.     
  546.     // Search for name
  547.     
  548.     cSound *s;
  549.     
  550.     for (s = sounds; s != 0 && !eq(_name, s->label); s = (cSound *)s->next);
  551.  
  552.     // Check if sequence exists
  553.  
  554.     if (s == 0)
  555.     {
  556.         seq.start_sound = 0;
  557.         seq.end_sound = 0;
  558.  
  559.         return;
  560.     }
  561.  
  562.     // Else store first picture
  563.     
  564.     seq.start_sound = s;
  565.     
  566.     // Get end of sequence
  567.     
  568.     for (; s->next != 0 && eq(_name, ((cSound *)s->next)->label); s = (cSound *)s->next);
  569.     
  570.     seq.end_sound = s;
  571. }
  572.  
  573. void cProperties::get_circles(char *_name, cCircle **list)
  574. {
  575.     ASSERT(_name != 0);
  576.     
  577.     *list = 0;
  578.     
  579.     for (cCircle *c = circle; c != 0; c = (cCircle *)c->next)
  580.         if (eq(c->label, _name))
  581.             new cCircle(list, c);
  582.         
  583.     ASSERT(*list != 0);
  584. }
  585.  
  586. void cProperties::get_spots(char *_name, cSpot **list)
  587. {
  588.     ASSERT(_name != 0);
  589.     
  590.     *list = 0;
  591.     
  592.     for (cSpot *s = spot; s != 0; s = (cSpot *)s->next)
  593.         if (eq(s->label, _name))
  594.             new cSpot(list, s);
  595.  
  596.     ASSERT(*list != 0);
  597. }
  598.